/*
 * ArchivoTexto.h
 *
 *  Created on: 17/10/2009
 *      Author: ngonzalez
 */

#ifndef ARCHIVOTEXTO_H_
#define ARCHIVOTEXTO_H_
#ifndef MAX_LENGTH
#define MAX_LENGTH 256
#endif



#include "stdlib.h"
#include <sstream>
#include <iosfwd>
#include <stdio.h>
#include <string.h>
#include "Archivo.h"

class ArchivoTexto : public Archivo {

private: std::fstream  archivo;  // referencia al archivo

public: string path;

  /**
   * Abre el archivo ubicado en el path pasado (debe incluir nombre completo) en modo lectura/escritura.
   * Deja el cursor al comienzo del mismo.
   * En caso de no existir el archivo, lo crea.
   * Si no puede realizar la operación, arroja una excepción
   */
public: ArchivoTexto(const std::string& path);

  /**
   * Cierra el archivo (no lo destruye físicamente
   */
public: ~ArchivoTexto();


public: virtual void create(const string& nombre);

/**
 * Metodo que salva en  disco y devuelve en que lugar de dicha
 * estructura se guardo la informacion
 */
public: virtual int saveData(Dato *data);

public: virtual int saveData(string data);


/**
 * Metodo que salva en  disco y devuelve en que lugar de dicha
 * estructura se guardo la informacion
 */
public: virtual int saveData(string data, int posicion);


public: virtual void SetPosicion(long int pos);

/**
 * Metodo que borra de la estructura el dato alojado en la posicion
 * indicada por el parametro position
 */
public: virtual void deleteData(int position);

/**
 * Metodo que, previamente consultando al indice sobre un dato y devolviendo este una posicion al archivo, devuelve
 * el dato en cuestion.
 */
public: virtual string getData(int position);

/**
 * Metodo que devuele el dato alojado en la posicion corriente del Archivo;
 */
public: virtual string getData();

public: string getPath() const;

public: void setPath(string path);


/**
 * Metodo que actualiza los datos alojados en la posicion pasada por parametro
 * con los datos del parametro data
 */
public: virtual void updateData(int position,Dato *data);


/**
 * Metodo que actualiza los datos alojados en la posicion pasada por parametro
 * con los datos del parametro data
 */
public: virtual void updateData(int position,string data);


/**
   * Escribe un caracter al archivo en la posición del cursor.
   * Luego de escribirlo, el cursor queda en la posición siguiente
   * Si no puede escribir, arroja una excepción
   */
private: void escribir(char c);

  /**
   * Escribe una cadena de caracteres al archivo en la posición del cursor.
   * Luego de escribirlo, el cursor queda en la posición siguiente al último caracter de la cadena
   *  Si no puede escribir, arroja una excepción
   */
public: void escribir(const std::string& cadena);

  /**
   * Posiciona el cursor en una nueva linea debajo de la actual
   * Si no puede hacerlo, arroja una excepción
   */
public: void terminarLinea();

  /**
   * Escribe una tabulación horizontal en el archivo, quedando el cursor en la posición siguiente
   * Si no puede hacerlo, arroja una excepción
   */
private: void tabular();

  /**
   * Lee del archivo una cadena de caracteres a partir de la posición actual del cursor y hasta:
   *  - Que se encuentre un fin de linea
   *  - Se lean MAX_LENGTH caracteres
   * El contenido leido se almacena en el parámetro "cadena"
   * Retorna true si pudo leer una linea, o false en caso contrario
   */
public: bool leerLinea(std::string &cadena );

  /**
   * Posiciona el cursor al comienzo del archivo
   */
public: void irAlPrincipio();

  /**
   * Posiciona el cursor al final del archivo
   */
public: void irAlFinal();

/**
 * Limpia el archivo dejandolo vacio
 */
public: void clean();

/**
 * Devuelve la cantidad de registros que tiene un archivo de texto
 */
private: string getTextFileSize();

/**
 * Se posiciona en el archivo de texto para sobrescribir la metada
 */
private: void seekToOverrideFileSize(int offset);

/**
 * Actualiza la metadata (FileSize)
 */
private: void updateTextFileSize(int olderFileSize);


/**
 * Usado para el cuando se borra una linea del archivo de texto. Este metodo determina
 * la longitud de la linea que sobrescribirá la linea existente
 */
private: void buildOverwritingLineLength(string line, string & myData);


/**
 * Is end of storage?
 */
public: virtual bool isEoS();

/**
 * Se mueve al principio de la estructura de almacenamiento
 */
public: virtual void firstPosition();

/**
 * devuelve un registro/linea al cual esta apuntando el corriente de la estructura
 */
private: string leerLinea();

/**
 * Borra el registro al cual apunta el corriente;
 */
public: virtual void deleteCurrent(int position);

public: virtual int getPosition();

public: virtual int getOldData();


};

#endif /* ARCHIVOTEXTO_H_ */
